//
//  JYRouterProtocol.swift
//  JYRouter
//
//  Created by huangguojian on 2021/9/15.
//

import UIKit

///路由器对象协议
public protocol JYRouterProtocol where Self: Codable {
    
    ///注册路由对应的控制器
    var controller: JYRoutable? { get }
    
    ///push过程中需要销毁的controller的类
    var willRemoveControllers: JYRouterWillRemoveControllersType { get }
    
    ///路由器跳转前置条件
    var shouldLink: Bool { get }
    
    ///不符合前置跳转条件后的处理
    func handelAfterLinkFail()
    
    /// 路由跳转，多个 JYRouterProtocol 可以通过扩展 JYRouterProtocol 统一实现
    func link(animated: Bool, callBack: @escaping (JYRouterModelType) -> Void)
    
    /// 提供 scheme://host 这种格式
    var schemeAndhost: (String, String) { get }
    
}

public extension JYRouterProtocol {
    
    /// 反序列化
    static func decode(from data: Data) throws -> Self {
        try JSONDecoder().decode(Self.self, from: data)
    }
    
    /// 路由跳转
    func link(by routerManager: any JYRouterManager.Type, animated: Bool, callBack: @escaping (JYRouterModelType) -> Void) {
        guard shouldLink else {
            handelAfterLinkFail()
            return
        }
        guard let controller else { return }
        
        controller.routeCallBack = callBack
        controller.hidesBottomBarWhenPushed = true
        
        switch controller.routeStyle {
        case .push:
            let nv = routerManager.currentNavigationController
            var viewControllers = nv.viewControllers
            
            switch willRemoveControllers {
            case .all:
                nv.setViewControllers([controller], animated: animated)
                return
            case .none:
                nv.pushViewController(controller, animated: animated)
                return
            case .include(let vcTypes):
                viewControllers = Array(viewControllers.drop(while: { vc in vcTypes.contains(where: { vc.isKind(of: $0) }) }))
            case .exclude(let vcTypes):
                viewControllers = viewControllers.filter { vc in vcTypes.contains(where: { vc.isKind(of: $0) }) }
            }
            
            viewControllers.append(controller)
            nv.setViewControllers(viewControllers, animated: animated)
        case .present:
            routerManager.getAppRootController().present(controller, animated: animated, completion: nil)
        case .tabbarSelect:
            routerManager.showTabbarControllerAndSelect(controller: controller, animated: animated)
        case .windowRoot:
            let window = (UIApplication.shared.delegate?.window!)!
            window.rootViewController = controller
            window.makeKeyAndVisible()
        }
    }
    
    /// 获取完整的路由链接，方便 debug
    var linkUrl: String {
        
        do {
            let data = try JSONEncoder().encode(self)
            let dic = try JSONSerialization.jsonObject(with: data) as! [String: [String: Any]]
            
            var component = URLComponents()
            component.scheme = schemeAndhost.0
            component.host = schemeAndhost.1
            component.path = "/" + dic.keys.first!
            let queryItems = dic.values.first!.map { URLQueryItem(name: $0.key, value: "\($0.value)") }
            component.queryItems = queryItems.isEmpty ? nil : queryItems
            return component.string ?? ""
            
        } catch {
            return ""
        }
    }
}
